<?php

use Service\Exception\ApiErrCode;
use Service\Kdniao\ShipperCodeMap;

class ControllerAccountOrder extends Controller {

    const REQUEST_KEY_ORDER_STATUS = 'status';
    const ORDER_STATUS_UNPAID = 'unpaid';
    const ORDER_STATUS_ALL = 'all';
    const ORDER_STATUS_NOT_REVIEWED = 'not_reviewed';
    const ORDER_STATUS_UNPAID_ID = '0';

    /**
     * @var ModelAccountOrder $modelAccountOrder
     */
    protected $modelAccountOrder;

    /**
     * ControllerAccountOrder constructor.
     *
     * @param $registry
     *
     * @throws Exception
     */
    public function __construct($registry)
    {
        parent::__construct($registry);

        $this->modelAccountOrder = $this->loadModel('account/order');
    }


    /**
     * @throws Exception
     */
    public function index() {
		if (!$this->customer->isLogged()) {
			$this->session->data['redirect'] = $this->url->link('account/order');

			$this->response->redirect($this->url->link('account/login'));
		}

        $this->modelAccountOrder->deleteOrdersUnpaid();

        $this->load->language('account/order');

		$this->document->setTitle($this->language->get('heading_title'));

		$url = '';

		if (isset($this->request->get['page'])) {
			$url .= '&page=' . $this->request->get['page'];
		}

		$data['breadcrumbs'] = array();

		$data['breadcrumbs'][] = array(
			'text' => $this->language->get('text_home'),
			'href' => $this->url->link('common/home')
		);

		$data['breadcrumbs'][] = array(
			'text' => $this->language->get('text_account'),
			'href' => $this->url->link('account/account')
		);

		$data['breadcrumbs'][] = array(
			'text' => $this->language->get('heading_title'),
			'href' => $this->url->link('account/order', $url)
		);

		if (isset($this->request->get['page'])) {
			$page = $this->request->get['page'];
		} else {
			$page = 1;
		}

		$filters = [
            'order_status_ids'    => $this->orderStatusKeywordToIds($this->requestGet(self::REQUEST_KEY_ORDER_STATUS)),
            'filter_not_reviewed' => $this->requestGet(self::REQUEST_KEY_ORDER_STATUS) === self::ORDER_STATUS_NOT_REVIEWED
        ];

		$order_total = $this->modelAccountOrder->getTotalOrders($filters);
		$all_order_total = $this->modelAccountOrder->getTotalOrders();
		$orders = $this->modelAccountOrder->getOrders(($page - 1) * 10, 10, $filters);

        $orders = $this->loadOrdersProducts($orders);
    
        $data['orders'] = [];
        foreach ($orders as $order) {
			$product_total = $this->modelAccountOrder->getTotalOrderProductsByOrderId($order['order_id']);
			$voucher_total = $this->modelAccountOrder->getTotalOrderVouchersByOrderId($order['order_id']);

			$data['orders'][] = [
                'order_id'        => $order['order_id'],
                'name'            => $order['fullname'],
                'status'          => $order['status'],
                'date_added'      => date($this->language->get('datetime_format'), strtotime($order['date_added'])),
                'product_num'     => $product_total + $voucher_total,
                'products'        => $product_total + $voucher_total,
                'order_products'  => $order['order_products'],
                'total'           => $this->currency->format($order['total'], $order['currency_code'], $order['currency_value']),
                'view'            => $this->url->link('account/order/info', 'order_id=' . $order['order_id']),
                'operate_actions' => $this->orderOperateActions($order),
                'logistic_action' => $this->orderLogisticAction($order),
            ];
        }

		$pagination = new Pagination();
		$pagination->total = $order_total;
		$pagination->page = $page;
		$pagination->limit = 10;
		$pagination->url = $this->url->link('account/order', 'page={page}&status=' . $this->requestGet('status'));

		$data['pagination'] = $pagination->render();

		$data['results'] = sprintf($this->language->get('text_pagination'), ($order_total) ? (($page - 1) * 10) + 1 : 0, ((($page - 1) * 10) > ($order_total - 10)) ? $order_total : ((($page - 1) * 10) + 10), $order_total, ceil($order_total / 10));

		$data['continue'] = $this->url->link('account/account');

		$data['column_left'] = $this->load->controller('common/column_left');
		$data['column_right'] = $this->load->controller('common/column_right');
		$data['content_top'] = $this->load->controller('common/content_top');
		$data['content_bottom'] = $this->load->controller('common/content_bottom');
		$data['footer'] = $this->load->controller('common/footer');
		$data['header'] = $this->load->controller('common/header');
        $data['status_buttons'] = $this->assembleOrderStatusButtons($order_total);
        $data['order_total'] = $all_order_total;

		$this->response->setOutput($this->load->view('account/order_list', $data));
	}

    /**
     * @return Action
     * @throws Exception
     */
    public function info() {
		$this->load->language('account/order');

		if (isset($this->request->get['order_id'])) {
			$order_id = $this->request->get['order_id'];
		} else {
			$order_id = 0;
		}

		if (!$this->customer->isLogged()) {
			$this->session->data['redirect'] = $this->url->link('account/order/info', 'order_id=' . $order_id);

			$this->response->redirect($this->url->link('account/login'));
		}

		$order_info = $this->modelAccountOrder->getOrder($order_id);
		if ($order_info) {
			$this->document->setTitle($this->language->get('text_order'));

			$url = '';

			if (isset($this->request->get['page'])) {
				$url .= '&page=' . $this->request->get['page'];
			}

			$data['breadcrumbs'] = array();

			$data['breadcrumbs'][] = array(
				'text' => $this->language->get('text_home'),
				'href' => $this->url->link('common/home')
			);

			$data['breadcrumbs'][] = array(
				'text' => $this->language->get('text_account'),
				'href' => $this->url->link('account/account')
			);

			$data['breadcrumbs'][] = array(
				'text' => $this->language->get('heading_title'),
				'href' => $this->url->link('account/order', $url)
			);

			$data['breadcrumbs'][] = array(
				'text' => $this->language->get('text_order'),
				'href' => $this->url->link('account/order/info', 'order_id=' . $this->request->get['order_id'] . $url)
			);

			if (isset($this->session->data['error'])) {
				$data['error_warning'] = $this->session->data['error'];

				unset($this->session->data['error']);
			} else {
				$data['error_warning'] = '';
			}

			if (isset($this->session->data['success'])) {
				$data['success'] = $this->session->data['success'];

				unset($this->session->data['success']);
			} else {
				$data['success'] = '';
			}

			if ($order_info['invoice_no']) {
				$data['invoice_no'] = $order_info['invoice_prefix'] . $order_info['invoice_no'];
			} else {
				$data['invoice_no'] = '';
			}

            $data['order_id'] = (int)$this->request->get['order_id'];
			$data['date_added'] = date($this->language->get('datetime_format'), strtotime($order_info['date_added']));

			$data['payment_address'] = address_format($order_info, $order_info['payment_address_format'], 'payment');
			$data['payment_method'] = $order_info['payment_method'];

			$orderStatus = $this->modelAccountOrder->getOrderStatus($order_info['order_status_id']);
            $data['order_status'] = $orderStatus['name'] ?? '';
            $data['is_pending_payment'] =  $orderStatus['order_status_id'] === self::ORDER_STATUS_UNPAID_ID; // 是否是未支付的订单

            $data['order_completed'] = $this->modelAccountOrder->isStatusComplete($order_info['order_status_id']);
            /** @var ModelAccountOrderAutoSign $modelOrderAutoSign */
            $modelOrderAutoSign = $this->loadModel('account/order_auto_sign');
            $auto_sign = $modelOrderAutoSign->findByOrderId($order_id);
            $data['order_should_sign_at'] = $auto_sign ? sprintf($this->language->get('auto_sign'), $auto_sign['should_sign_at']) : null;

			if ($order_info['shipping_method']) {
				$data['shipping_address'] = address_format($order_info, $order_info['shipping_address_format'], 'shipping');
				$data['shipping_method'] = $order_info['shipping_method'];
			} else {
				$data['shipping_address'] = '';
				$data['shipping_method'] = '';
			}

			$this->load->model('catalog/product');
			$this->load->model('tool/upload');

			// Products
			$data['products'] = array();

			$products = $this->modelAccountOrder->getOrderProducts($this->request->get['order_id']);

            $products = $this->loadOrderProductsReview($products);

			foreach ($products as $order_product) {
				$option_data = array();

				$options = $this->modelAccountOrder->getOrderOptions($this->request->get['order_id'], $order_product['order_product_id']);

				foreach ($options as $option) {
					if ($option['type'] != 'file') {
						$value = $option['value'];
					} else {
						$upload_info = $this->model_tool_upload->getUploadByCode($option['value']);

						if ($upload_info) {
							$value = $upload_info['name'];
						} else {
							$value = '';
						}
					}

					$option_data[] = array(
						'name'  => $option['name'],
						'value' => (utf8_strlen($value) > 20 ? utf8_substr($value, 0, 20) . '..' : $value)
					);
				}

				$product_info = $this->model_catalog_product->getProduct($order_product['product_id']);

				if ($product_info) {
					$reorder = $this->url->link('account/order/reorder', 'order_id=' . $order_id . '&order_product_id=' . $order_product['order_product_id']);
				} else {
					$reorder = '';
				}

				$data['products'][] = array(
					'name'          => $order_product['name'],
                    'model'         => $order_product['model'],
                    'option'        => $option_data,
                    'quantity'      => $order_product['quantity'],
                    'price'         => $this->currency->format($order_product['price'] + ($this->config->get('config_tax') ? $order_product['tax'] : 0), $order_info['currency_code'], $order_info['currency_value']),
                    'total'         => $this->currency->format($order_product['total'] + ($this->config->get('config_tax') ? ($order_product['tax'] * $order_product['quantity']) : 0), $order_info['currency_code'], $order_info['currency_value']),
                    'reorder'       => $reorder,
                    'return'        => $this->orderReturnAction($order_info, $order_product),
                    'image'         => image_resize($product_info ? $product_info['image'] : null),
                    'review'        => $order_product['review'],
                    'review_action' => $this->orderProductReviewAction($order_info, $order_product),
                    'href'          => $this->url->link('product/product','product_id=' . $order_product['product_id']),
				);
			}

			// Voucher
			$data['vouchers'] = array();

			$vouchers = $this->modelAccountOrder->getOrderVouchers($this->request->get['order_id']);

			foreach ($vouchers as $voucher) {
				$data['vouchers'][] = array(
					'description' => $voucher['description'],
					'amount'      => $this->currency->format($voucher['amount'], $order_info['currency_code'], $order_info['currency_value'])
				);
			}

			// Totals
			$data['totals'] = array();

			$totals = $this->modelAccountOrder->getOrderTotals($this->request->get['order_id']);

			foreach ($totals as $total) {
				$data['totals'][] = array(
					'title' => $total['title'],
					'text'  => $this->currency->format($total['value'], $order_info['currency_code'], $order_info['currency_value']),
				);
			}

			$data['comment'] = nl2br($order_info['comment']);

			// History
			$data['histories'] = array();

			$results = $this->modelAccountOrder->getOrderHistories($this->request->get['order_id']);

			foreach ($results as $result) {
				$data['histories'][] = array(
					'date_added' => date($this->language->get('datetime_format'), strtotime($result['date_added'])),
					'status'     => $result['status'],
					'comment'    => $result['notify'] ? nl2br($result['comment']) : ''
				);
			}

			$data['continue'] = $this->url->link('account/order');

			$data['column_left'] = $this->load->controller('common/column_left');
			$data['column_right'] = $this->load->controller('common/column_right');
			$data['content_top'] = $this->load->controller('common/content_top');
			$data['content_bottom'] = $this->load->controller('common/content_bottom');
			$data['footer'] = $this->load->controller('common/footer');
			$data['header'] = $this->load->controller('common/header');

			$this->response->setOutput($this->load->view('account/order_info', $data));
		} else {
			return new Action('error/not_found');
		}
	}

	public function reorder() {
		$this->load->language('account/order');

		if (isset($this->request->get['order_id'])) {
			$order_id = $this->request->get['order_id'];
		} else {
			$order_id = 0;
		}

		$order_info = $this->modelAccountOrder->getOrder($order_id);

		if ($order_info) {
			if (isset($this->request->get['order_product_id'])) {
				$order_product_id = $this->request->get['order_product_id'];
			} else {
				$order_product_id = 0;
			}

			$order_product_info = $this->modelAccountOrder->getOrderProduct($order_id, $order_product_id);

			if ($order_product_info) {
				$this->load->model('catalog/product');

				$product_info = $this->model_catalog_product->getProduct($order_product_info['product_id']);

				if ($product_info) {
					$option_data = array();

					$order_options = $this->modelAccountOrder->getOrderOptions($order_product_info['order_id'], $order_product_id);

					foreach ($order_options as $order_option) {
						if ($order_option['type'] == 'select' || $order_option['type'] == 'radio' || $order_option['type'] == 'image') {
							$option_data[$order_option['product_option_id']] = $order_option['product_option_value_id'];
						} elseif ($order_option['type'] == 'checkbox') {
							$option_data[$order_option['product_option_id']][] = $order_option['product_option_value_id'];
						} elseif ($order_option['type'] == 'text' || $order_option['type'] == 'textarea' || $order_option['type'] == 'date' || $order_option['type'] == 'datetime' || $order_option['type'] == 'time') {
							$option_data[$order_option['product_option_id']] = $order_option['value'];
						} elseif ($order_option['type'] == 'file') {
							$option_data[$order_option['product_option_id']] = $this->encryption->encrypt($this->config->get('config_encryption'), $order_option['value']);
						}
					}

					$this->cart->add($order_product_info['product_id'], $order_product_info['quantity'], $option_data);

					$this->session->data['success'] = sprintf($this->language->get('text_success'), $this->url->link('product/product', 'product_id=' . $product_info['product_id']), $product_info['name'], $this->url->link('checkout/cart'));

					unset($this->session->data['shipping_method']);
					unset($this->session->data['shipping_methods']);
					unset($this->session->data['payment_method']);
					unset($this->session->data['payment_methods']);
				} else {
					$this->session->data['error'] = sprintf($this->language->get('error_reorder'), $order_product_info['name']);
				}
			}
		}

		$this->response->redirect($this->url->link('account/order/info', 'order_id=' . $order_id));
	}

    /**
     * @param array $orders
     *
     * @return array
     *
     * @throws Exception
     */
    private function loadOrdersProducts(array $orders)
    {
        $order_ids = array_column($orders, 'order_id');

        /** @var ModelAccountOrder $accountOrder */
        $accountOrder = $this->loadModel('account/order');

        $orderProducts = $accountOrder->getOrdersProducts($order_ids);

        $orderProducts = $this->loadOrderProductsImage($orderProducts);

        $orderProducts = $this->loadOrderProductsLink($orderProducts);

        foreach ($orders as $idx => $order) {
            $orders[$idx]['order_products'] = array_filter($orderProducts, function (array $orderProduct) use ($order) {
                return (int) $orderProduct['order_id'] === (int) $order['order_id'];
            });
        }

        return $orders;
    }

    /**
     * 给加入link链接到商品详情
     * @param array $orderProducts
     * @return array
     */
    public function loadOrderProductsLink(array $orderProducts)
    {
        foreach ($orderProducts as $idx => $orderProduct) {
            $orderProducts[$idx]['link'] = $this->url->link('product/product', 'product_id=' . $orderProduct['product_id']);
        }
        return $orderProducts;
    }

    /**
     * @param array $orderProducts
     *
     * @return array
     *
     * @throws Exception
     */
    private function loadOrderProductsImage(array $orderProducts)
    {
        $product_ids = array_column($orderProducts, 'product_id');

        /** @var ModelCatalogProduct $catalogProduct */
        $catalogProduct = $this->loadModel('catalog/product');
        $products = $catalogProduct->getProductsByKeys($product_ids);

        foreach ($orderProducts as $idx => $orderProduct) {
            $match_product = array_first($products, function (array $product) use ($orderProduct) {
                return (int) $product['product_id'] === (int) $orderProduct['product_id'];
            });

            $orderProducts[$idx]['image'] = $match_product['image'] ?? null;
        }

        return $orderProducts;
    }

    /**
     * @param string
     *
     * @return array
     */
    private function orderOperateActions($order)
    {
        $status = (int) $order['order_status_id'];
        $order_id = $order['order_id'];
        $order_query = http_build_query(compact('order_id'));
        $actions = [
            'pay'             => null,
            'cancel'          => null,
            'confirm_receipt' => null,
        ];

        if ($status === ModelAccountOrder::ORDER_STATUS_ID_UNPAID) { // 去支付
            $actions['pay'] =  $this->url->link('checkout/checkout/connect', $order_query);
            $actions['cancel'] =  $this->url->link('account/order/cancel', $order_query);
        }

        if (in_array($status, $this->config->get('config_processing_status'))) { // 确认收货
            $actions['confirm_receipt'] = $this->url->link('account/order/confirmReceipt', $order_query);
        }

        return $actions;
    }

    /**
     * 确认收货
     *
     * @throws Exception
     */
    public function confirmReceipt()
    {
        $order_id = $this->requestGet('order_id');
        $order = $this->modelAccountOrder->getOrder($order_id);
        $config_status_ids = $this->config->get('config_complete_status');

        if ($order && $config_status_ids
            && is_array($config_status_ids)
            && is_numeric(head($config_status_ids))
        ) {
            $complete_status_id = head($config_status_ids);
            /** @var ModelCheckoutOrder $modelCheckoutOrder */
            $modelCheckoutOrder = $this->loadModel('checkout/order');
            $modelCheckoutOrder->addOrderHistory($order_id, $complete_status_id);
        }

        // finally redirect order list
        $order_list_url = $this->url->link('account/order');
        $this->response->redirect($order_list_url);
    }

    /**
     * 评价订单
     *
     * @throws Exception
     */
    public function addProductReview()
    {
        $order_product_id = $this->requestAny('order_product_id');
        $order_id = $this->requestAny('order_id');
        $customer = $this->cartCustomer();
        if (! ($customer->isLogged() && $this->isPost() && $order_product_id && $order_id)) {
            $this->jsonError('Method not allow or Customer not login', ApiErrCode::REQUEST_PARAMS_ERROR);
        }

        $order = $this->modelAccountOrder->getOrder($order_id);
        $is_same_customer = (int) $order['customer_id'] === (int) $customer->getId();
        if (! ($order && $is_same_customer)) {
            $this->jsonError('Order not match customer', ApiErrCode::OPERATE_FAILED);
        }

        /** @var ModelCatalogReview $modelCatalogReview */
        $modelCatalogReview = $this->loadModel('catalog/review');
        $existReview = $modelCatalogReview->findByOrderProductId($order_product_id);
        if ($existReview) {
            $this->jsonError('Review already exist', ApiErrCode::DB_ITEM_EXIST);
        }

        $order_product = $this->modelAccountOrder->getOrderProduct($order_id, $order_product_id);
        if (! $order_product) {
            $this->jsonError('Order product not found', ApiErrCode::DB_ITEM_NOT_FOUND);
        }

        $created = $modelCatalogReview->addOrderReview([
            'author'           => $customer->getFullName(),
            'customer_id'      => (int) $customer->getId(),
            'order_product_id' => (int) $order_product_id,
            'product_id'       => (int) $order_product['product_id'],
            'rating'           => $this->requestPost('rating', ''),
            'text'             => $this->requestPost('text', ''),
        ]);

        $images = $this->requestAny('images');
        if (! empty($images) && is_array($images)) {

            /** @var ModelCatalogReviewImage $modelCatalogReviewImg */
            $modelCatalogReviewImg = $this->loadModel('catalog/review_image');
            $modelCatalogReviewImg->insertReviewImages($created->review_id, $images);
        }

        $this->responseOK(compact('created'));
    }

    /**
     * @param $order
     *
     * @return string|null
     */
    private function orderLogisticAction($order)
    {
        $has_logistic = ! empty($order['shipping_shipper_code']) && ! empty($order['shipping_logistic_code']);
        $extension_status_on = $this->config->get('logistic_kdniao_status');

        if ($has_logistic && $extension_status_on) {
            $query = http_build_query(['order_id' => $order['order_id']]);
            $url = $this->url->link('account/order/logistic', $query);
            return $url;
        } else {
            return null;
        }
    }

    /**
     * 订单物流查询页面
     *
     * @throws Exception
     */
    public function logistic()
    {
        $this->load->language('account/order_logistic');
        if (! $this->cartCustomer()->isLogged()) {
            $this->redirectToIndex();
        }

        $order_id = $this->requestGet('order_id');
        if (! $order_id) {
            $this->redirectToIndex();
        }

        $order = $this->modelAccountOrder->getOrder($order_id);

        if (! $order || ! $order['shipping_shipper_code'] || ! $order['shipping_logistic_code']) {
            $this->redirectToIndex();
        }

        list($order) = $this->loadOrdersProducts([$order]);
        $order['shipping_shipper'] = ShipperCodeMap::codeName($order['shipping_shipper_code']) ?: 'unknown';
        $order['shipping_address'] = address_format($order, $order['shipping_address_format'], 'shipping');

        $data = [
            'order'          => $order,
            'traces'         => $this->queryLogisticTraces($order),
            'column_left'    => $this->load->controller('common/column_left'),
            'column_right'   => $this->load->controller('common/column_right'),
            'content_top'    => $this->load->controller('common/content_top'),
            'content_bottom' => $this->load->controller('common/content_bottom'),
            'footer'         => $this->load->controller('common/footer'),
            'header'         => $this->load->controller('common/header'),
        ];

        $this->response->setOutput(
            $this->load->view('account/order_logistic', $data)
        );
    }

    private function redirectToIndex()
    {
        // finally redirect order list
        $order_list_url = $this->url->link('account/order');
        $this->response->redirect($order_list_url);
    }

    /**
     * @param $order
     *
     * @return array
     */
    private function queryLogisticTraces($order)
    {
        $query = http_build_query([
            'logistic_code' => $order['shipping_logistic_code'],
            'shipper_code'  => $order['shipping_shipper_code'],
        ]);
        $host = parse_url(HTTP_SERVER, PHP_URL_HOST);
        $api = "http://$host/api/v1/app/common/logistic-trace?$query";
        $json = file_get_contents($api);
        $logistic_data = json_decode($json, true);

        return $logistic_data;
    }

    /**
     * @param $order_info
     * @param $order_product
     *
     * @return string|null
     */
    private function orderProductReviewAction($order_info, $order_product)
    {
        $order_status_id = $order_info['order_status_id'];
        $complete_status = $this->config->get('config_complete_status');

        if (in_array($order_status_id, $complete_status) && ! $order_product['review']) {
            $query = http_build_query([
                'order_id'         => $order_info['order_id'],
                'order_product_id' => $order_product['order_product_id']
            ]);

            return $this->url->link('account/order/addProductReview', $query);
        } else {
            return null;
        }
    }

    /**
     * @param array $order_products
     *
     * @return array
     * @throws Exception
     */
    private function loadOrderProductsReview(array $order_products): array
    {
        $order_product_ids = array_column($order_products, 'order_product_id');

        /** @var ModelCatalogReview $modelCatalogReview */
        $modelCatalogReview = $this->loadModel('catalog/review');
        $exist_reviews = $modelCatalogReview->getReviewsByOrderProductIds($order_product_ids);

        return array_map(function (array $order_product) use ($exist_reviews) {
            $match_reviews = array_filter($exist_reviews, function (array $exist_review) use ($order_product) {
                return (int) $exist_review['order_product_id'] === (int) $order_product['order_product_id'];
            });

            $order_product['review'] = count($match_reviews) ? head($match_reviews) : null;

            return $order_product;
        }, $order_products);
    }

    /**
     * @param $order_info
     * @param $order_product
     *
     * @return string|null
     * @throws Exception
     */
    private function orderReturnAction($order_info, $order_product)
    {
        // 不处于未付款均可售后
        $status = (int) $order_info['order_status_id'];
        if (! $status) { // ! in_array($status, $this->config->get('config_complete_status'))
            return null;
        }

        $order_id = $order_info['order_id'];
        $product_id = $order_product['product_id'];
        $order_product_id = $order_product['order_product_id'];

        /** @var ModelAccountReturn $modelAccountReturn */
        $modelAccountReturn = $this->loadModel('account/return');
        if ($modelAccountReturn->findByOrderAndProductId($order_id, $product_id)) {
            return null;
        }

        $action = $this->url->link(
            'account/return/add',
            http_build_query(compact('order_id', 'product_id', 'order_product_id'))
        );

        return $action;
    }

    /**
     * @param $status
     *
     * @return array|null
     */
    private function orderStatusKeywordToIds($status)
    {
        switch ($status) {
            case self::ORDER_STATUS_UNPAID :
                return [0];

            case self::ORDER_STATUS_NOT_REVIEWED :
                return array_values($this->config->get('config_complete_status'));

            case self::ORDER_STATUS_ALL :
            default :
                return null;
        }
    }
    
    /**
     * @param int $current_total
     * @return array
     */
    private function assembleOrderStatusButtons($current_total)
    {
        $req_status = $this->requestGet(self::REQUEST_KEY_ORDER_STATUS);
        if ($req_status === self::ORDER_STATUS_UNPAID) {
            $unpaid_count = $current_total;
        } else {
            $unpaid_count = $this->modelAccountOrder->getTotalOrders([
                'order_status_ids' => $this->orderStatusKeywordToIds(self::ORDER_STATUS_UNPAID)
            ]);
        }
    
        if ($req_status === self::ORDER_STATUS_NOT_REVIEWED) {
            $not_reviewed_count = $current_total;
        } else {
            $not_reviewed_count = $this->modelAccountOrder->getTotalOrders([
                'order_status_ids'    => $this->orderStatusKeywordToIds(self::ORDER_STATUS_NOT_REVIEWED),
                'filter_not_reviewed' => true
            ]);
        }

        return [
            [
                'name'   => $this->language->get('btn_status_all'),
                'action' => $this->orderStatusBtnActionLink(self::ORDER_STATUS_ALL),
                'active' => $this->isOrderStatusBtnActive(self::ORDER_STATUS_ALL)
            ],
            [
                'name'   => sprintf($this->language->get('btn_status_unpaid'), $unpaid_count),
                'action' => $this->orderStatusBtnActionLink(self::ORDER_STATUS_UNPAID),
                'active' => $this->isOrderStatusBtnActive(self::ORDER_STATUS_UNPAID)
            ],
            [
                'name'   => sprintf($this->language->get('btn_status_not_reviewed'), $not_reviewed_count),
                'action' => $this->orderStatusBtnActionLink(self::ORDER_STATUS_NOT_REVIEWED),
                'active' => $this->isOrderStatusBtnActive(self::ORDER_STATUS_NOT_REVIEWED)
            ],
        ];
    }

    private function orderStatusBtnActionLink($btn_status)
    {
        $query = http_build_query([
            'status' => $btn_status
        ]);

        return $this->url->link('account/order', $query);
    }

    private function isOrderStatusBtnActive($btn_status)
    {
        $request_status = $this->requestGet(self::REQUEST_KEY_ORDER_STATUS, self::ORDER_STATUS_ALL);

        return $btn_status === $request_status;
    }

    /**
     * 取消订单
     */
    public function cancel()
    {
        $this->checkCustomerLogged();

        $this->load->language('account/order');

        $order_id = $this->requestAny('order_id');
        if (! $order_id) {
            $this->session->data['error_tips'] []= $this->language->get('no_order_id');
            $this->redirectToIndex();
        }

        $order = $this->modelAccountOrder->getOrder($order_id);
        if (! $order || ((int) $order['order_status_id']) !== ModelAccountOrder::ORDER_STATUS_ID_UNPAID) {
            $this->session->data['error_tips'] []= $this->language->get('order_not_exit');
            $this->redirectToIndex();
        }

        $deleted = $this->modelAccountOrder->delete($order_id);
        if ($deleted) {
            $this->session->data['success_tips'] []= $this->language->get('cancel_success');
        } else {
            $this->session->data['error_tips'] []= $this->language->get('cancel_error');
        }
        $this->redirectToIndex();
    }

    private function checkCustomerLogged()
    {
        if (!$this->customer->isLogged()) {
            $this->session->data['redirect'] = $this->url->link('account/order');

            $this->redirectToIndex();
        }
    }
}
